home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Mania 6
/
MacMania 6.toast
/
/
Tools&Utilities
/
EnterAct Stuff
/
Drag_on Modules
/
hAWK programs
/
$Whazzat
< prev
next >
Wrap
Text File
|
1993-04-09
|
7KB
|
265 lines
#$Whazzat: undeclarate (translate to English) most C declarations.
#Typically run this on one declaration at a time by
#selecting the declaration in the front text window and
#running this on “Front text selection”. Output is to stdout.
#If you run this on several declarations at once, each declaration
#(except maybe the last) should be terminated with a semicolon.
#Not for function/struct/union/enum definitions, and any comments
#should start and end on the same line.
#
#See “whazzatTest” for some example declarations.
# (You can run this program on all of whazzatTest at once)
#
#This is good enough to untangle a great many declarations,
#but not good enough to verify that a declaration is correct.
#
#If called from within EnterAct with a project open (and a
#dictionary built for the project), type specifications are
#extended to all typedefs, structs, unions, and enums defined
#in the source code for your project.
#For example, if your project contains a definition of NODE,
#then "NODE *" appearing in a declaration will be translated
# to "pointer to NODE"; if you have no proect open or NODE
#cannot be found in your project dictionary, then "NODE *"
#will be translated to just "pointer to", type left unspecified.
#For a (simpler) C version of this, see
# "The C Programming Language" by Kernighan & Ritchie, pg 122
# and "The C Answer Book" by Tondo & Gimpel, pg 140, 146
# (both published by Prentice Hall)
# User’s Manual references:
# «hAWK User’s Manual» «F Running hAWK programs»
# «hAWK User’s Manual» «L 5 Regular expressions»
# «hAWK User’s Manual» «M 5 Built-in string and file functions»
# «hAWK User’s Manual» «K 4 Built-in variables»
# «hAWK User’s Manual» «K 8 Arrays»
# «hAWK User’s Manual» «N User-defined functions»
# «hAWK User’s Manual» «P 3 The getline function»
# «hAWK User’s Manual» «O 3 Output into files»
# «hAWK User’s Manual» «Q The hAWK function»
BEGIN { if (ARGC != 2) # comment this out to allow multiple files (!?)
{
print "Whoa, just one little bit at a time please."
exit
}
min_line_width = 60;
#Some "enumerated" constants
NAME = 1; PARENS = 2; BRACKETS = 3; DDD = 4;
NO = 0; YES = 1; EOF = -1;
#Some keywords, associatively arrayed:
#specifiers
types["char"] = 1
types["int"] = 1
types["void"] = 1
types["long"] = 1
types["float"] = 1
types["double"] = 1
types["short"] = 1
types["..."] = 1
#qualifiers
typeq["const"] = 1
typeq["volatile"] = 1
typeq["unsigned"] = 1
typeq["signed"] = 1
typeq["struct"] = 1
typeq["union"] = 1
typeq["enum"] = 1
typeq["pascal"] = 1
typeq["Pascal"] = 1
prevtoken = NO;
Whazzat();
}
function Whazzat()
{
while (gettoken() != EOF)
{
if (token == "extern" || token == "static")
{
gettoken();
}
datatype = token
while (typequal() == YES)
{
gettoken();
datatype = datatype " " token
}
out = ""
name = ""
dcl();
nicely_print_decl();
}
}
function dcl( ns)
{
for (ns = 0; gettoken() == "*"; )
++ns;
dirdcl();
while (ns-- > 0)
out = out " pointer to"
}
function dirdcl( type)
{
if (tokentype == "(")
{
dcl();
if (tokentype != ")")
errmsg("Error: missing )")
}
else if (tokentype == NAME)
{
if (name == "")
name = token
}
else
prevtoken = YES;
while ((type = gettoken()) == PARENS ||
type == BRACKETS || type == "(")
{
if (type == PARENS)
out = out " function returning"
else if (type == "(")
{
out = out " function expecting"
parmdcl();
out = out " and returning"
}
else
{
out = out " array" token " of"
}
}
}
function errmsg(msg)
{
prevtoken = YES
print msg
}
function parmdcl()
{
do
{
dclspec();
} while (tokentype == ",");
if (tokentype != ")")
errmsg("missing ) in parameter declaration");
}
function dclspec( temp)
{
gettoken();
do
{
if (tokentype != NAME && tokentype != DDD)
{
prevtoken = YES
dcl();
}
else if (typespec() == YES || typequal() == YES)
{
temp = temp " " token
gettoken();
}
else #ignore it - typically a name for a parameter eg (int x, int y,...)
gettoken();# or errmsg("unknown type in parameter list");
} while (tokentype != "," && tokentype != ")");
out = out temp
if (tokentype == ",")
out = out ","
}
function typespec( type)
{
if (token in types)
return YES;
else if ((type = lookup(token)) == 16 || # typedef
type == 32 || type == 64 || # struct, union tag
type == 128) # enum tag
return YES;
return NO;
}
function typequal()
{
if (token in typeq)
return YES;
return NO;
}
#Read in a line at a time, and trim tokens from
#beginning of line. A bit wasteful, but time is not
#critical. Type of token is returned, and placed in tokentype;
#the token string is placed in token. Note no “ungetch()” is
#required, because the matches go just the right distance.
function gettoken()
{
if (tokentype == EOF)
return EOF;
if (prevtoken == YES)
{
prevtoken = NO
return tokentype;
}
#Get next line if needed
while (length(line) == 0)
{
if (getline line <= 0)
return tokentype = EOF;
sub(/^[ \t]+/, "", line) #null out blank line - rarely needed
sub(/^\/\*.*\*\//, "", line) #kill one-line comment
}
#remove leading white space and comments on one line
sub(/^[ \t]+/, "", line)
sub(/^\/\*.*\*\//, "", line)
if ((match(line, /^\(\)/) && (tokentype = PARENS)) || # ()
(match(line, /^\(/) && (tokentype = "(")) || # ( etc
(match(line, /^\[([^\]])*\]/) && (tokentype = BRACKETS)) || # [...]
(match(line, /^\.\.\./) && (tokentype = DDD)) || #variable args ...
(match(line, /^[A-Za-z_][A-Za-z0-9_]*/) && (tokentype = NAME))) # a C word
{
token = substr(line, 1, RLENGTH)
line = substr(line, RLENGTH + 1)
return tokentype
}
else
{
tokentype = substr(line,1,1)
line = substr(line, 2)
return tokentype
}
}
function nicely_print_decl( total_decl, one_line, tabber, i, len)
{
#print name ":", out, datatype -- works, but may produce long line
#min_line_width determines rough width of long lines
total_decl = name ": " out " " datatype;
tabber = ""
while ((len = length(total_decl)) > min_line_width)
{
i = min_line_width
#Round up to nearest word end.
while (i <= len && substr(total_decl, i, 1) ~ /[A-Za-z0-9_]/)
++i;
one_line = substr(total_decl, 1, i)
print tabber one_line
#Skip trailing space.
while (i <= len && substr(total_decl, i, 1) ~ /[^A-Za-z0-9_]/)
++i;
total_decl = substr(total_decl, i)
if (tabber == "")
tabber = "\t"
}
if (total_decl != "")
print tabber total_decl;
}